﻿#include "AF_Image.h"
#include "AF_Platform.h"

namespace AF
{
	Link<Image*> Image::ImageLink;

	Image* Image::Create()
	{
		Image* _pimgNew = AF_NEW(Image);
		ImageLink.Add(_pimgNew);
		return _pimgNew;
	}

	Image* Image::Create(const _STRING strPathName)
	{
		Image* _pimgNew = AF_NEW(Image);

		if(_pimgNew->SetImageHandle(strPathName))
		{
			ImageLink.Add(_pimgNew);
		}
		else
		{
			AF_DELETE(_pimgNew);
			_pimgNew = NULL;
		}

		return _pimgNew;
	}

	Image* Image::Create(Package* pPackage, const _STRING strImageName)
	{
		AF_CHECK_R(pPackage != NULL, NULL);
		AF_CHECK_R(strImageName != "", NULL);

		Image* _pimgNew = AF_NEW(Image);

		if(_pimgNew->SetImageHandle(pPackage, strImageName))
		{
			ImageLink.Add(_pimgNew);
		}
		else
		{
			AF_DELETE(_pimgNew);
			_pimgNew = NULL;
		}

		return _pimgNew;
	}

	Image* Image::Create(
			ImageHandle hImage,
			const UINT nWidth,
			const UINT nHeight,
			ImageInfo& ii
		)
	{
		AF_CHECK_R(hImage != NULL, NULL);

		Image* _pimgNew = AF_NEW(Image);

		if(_pimgNew->SetImageHandle(hImage, nWidth, nHeight, ii))
		{
			ImageLink.Add(_pimgNew);
		}
		else
		{
			AF_DELETE(_pimgNew);
			_pimgNew = NULL;
		}

		return _pimgNew;
	}

	Image* Image::Create(unsigned int nWidth, unsigned int nHeight)
	{
		Image* _pimgNew = AF_NEW(Image);

		if(_pimgNew->SetImageHandle(nWidth, nHeight))
		{
			ImageLink.Add(_pimgNew);
		}
		else
		{
			AF_DELETE(_pimgNew);
			_pimgNew = NULL;
		}

		return _pimgNew;
	}

	bool Image::Destroy(Image* pimgOne)
	{
		AF_CHECK_R(pimgOne != NULL, false);

		if(!ImageLink.Remove(pimgOne))
			return false;

		AF_DELETE(pimgOne);

		return true;
	}

	bool Image::DestroyAll()
	{
		int _nCount = ImageLink.GetCount();

		Image** _ppImages = AF_NEW_ARY(Image*, _nCount);

		if(!ImageLink.Clean(_ppImages))
		{
			AF_DELETE_ARY(_ppImages);
			return false;
		}
		
		for(int i = 0; i < _nCount; i++)
		{
			AF_DELETE(_ppImages[i]);
		}
		AF_DELETE_ARY(_ppImages);

		return true;
	}

	int Image::GetLinkCount()
	{
		return ImageLink.GetCount();
	}



	Image::Image() :
		ATTRIB(Clip)(AF_RECT_NULL),
// 		ATTRIB(BlendType)(0),
		m_hImage(NULL),
		m_hTransform(NULL),
		m_bDiskFile(false)
	{
		memset(&m_iiOriginal, 0, sizeof(ImageInfo) - sizeof(Bundle));
		m_nGType = GRAPHICS_IMAGE;
	}

	Image::~Image()
	{
		Release();
	}

	bool Image::SetImageHandle(const _STRING strPathName)
	{
		ImageHandle _hImage = AF_pTHEPLATFORM->CreateImage(strPathName, AF_ARG_SIZE(GetSize()), GetImageInfo());

		if(_hImage == NULL)
			return false;

		Release();
		m_hImage = _hImage;
//		SetClip(0, 0, AF_ARG_SIZE(GetSize()));

		m_bDiskFile = true;

		return true;
	}

	bool Image::SetImageHandle(Package* pPackage, const _STRING strImageName)
	{
		ImageHandle _hImage = pPackage->GetImageHandle(strImageName, AF_ARG_SIZE(GetSize()), GetImageInfo());

		if(_hImage == NULL)
			return false;

		Release();
		m_hImage = _hImage;
//		SetClip(0, 0, AF_ARG_SIZE(GetSize()));

		return true;
	}

	bool Image::SetImageHandle(
			ImageHandle hImage,
			const UINT nWidth,
			const UINT nHeight,
			ImageInfo& ii
		)
	{
		AF_CHECK_R(hImage != NULL, false);

		Release();
		m_hImage = hImage;
		SetSize(nWidth, nHeight);
		_MEMCPY(&m_iiOriginal, &ii, sizeof(ImageInfo));
//		SetClip(0, 0, AF_ARG_SIZE(GetSize()));

		return true;
	}

	bool Image::SetImageHandle(const UINT nWidth, const UINT nHeight)
	{
		ImageHandle _hImage = AF_pTHEPLATFORM->CreateImage(nWidth, nHeight, m_iiOriginal);

		if(_hImage == NULL)
			return false;

		Release();
		m_hImage = _hImage;
		SetSize(nWidth, nHeight);
//		SetClip(0, 0, AF_ARG_SIZE(GetSize()));

		return true;
	}

	ImageHandle Image::GetImageHandle(bool bIsTransform)
	{
		if(!bIsTransform)
			return m_hImage;

		return (m_hTransform == NULL) ? m_hImage : m_hTransform;
	}

	bool Image::CopyImage(Image* pimgDis, int nX, int nY, UINT nWidth, UINT nHeight)
	{
		AF_CHECK_R(pimgDis != NULL, false);

		Release();
		m_hImage = pimgDis->GetImageHandle(true);
		_MEMCPY(&m_iiOriginal, &pimgDis->GetImageInfo(), sizeof(ImageInfo));
		SetSize(pimgDis->GetSize());
		SetClip(nX, nY, nWidth, nHeight);

		return true;
	}

 	void Image::SetTransparent(float fTransparent)
 	{
 		if(fTransparent > 0.0f)
 		{
 			if(fTransparent > 100.0f)
 				fTransparent = 100.0f;
 			float _fAlpha = 255.0f / 100 * fTransparent;
 			SetAlpha((unsigned char)_fAlpha);
 		}
 	}

	void Image::SetClip(int nX, int nY, UINT nWidth, UINT nHeight)
	{
		Rect _rect;
		_rect.nX = nX;
		_rect.nY = nY;
		_rect.nWidth = nWidth;
		_rect.nHeight = nHeight;

		SetClip(_rect);
	}

	void Image::Release()
	{
		if(m_bDiskFile && m_hImage != NULL)
		{
			AF_pTHEPLATFORM->DeleteImage(m_hImage);
			m_hImage = NULL;
		}

		if(m_hTransform != NULL)
		{
			AF_pTHEPLATFORM->DeleteImage(m_hTransform);
			m_hTransform = NULL;
		}

		m_bDiskFile = false;
	}
}